package com.study.springCustom.spring.reader;

import com.study.springCustom.spring.ioc.BeanDefinition;
import com.study.springCustom.spring.ioc.PropertyValue;
import com.study.springCustom.spring.ioc.RuntimeBeanReference;
import com.study.springCustom.spring.ioc.TypedStringValue;
import com.study.springCustom.spring.registry.BeanDefinitionRegistry;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.InputStream;
import java.util.List;

public class DefaultBeanDefinitionDocumentReader implements BeanDefinitionDocumentReader{

    private BeanDefinitionRegistry registry;

    public DefaultBeanDefinitionDocumentReader(BeanDefinitionRegistry registry) {
        this.registry = registry;
    }

    @Override
    public void loadBeanDefinitions(Element rootElement) {
        List<Element> elements = rootElement.elements();
        for (Element element : elements) {
            String name = element.getName();
            if (name.equals("bean")){
                parseDefaultElement(element);
            }else{
                parseCustomElement(element);
            }
        }
    }

    private void parseCustomElement(Element element) {

    }

    /**
     *
     * @param element <bean></bean>
     */
    private void parseDefaultElement(Element element) {
        String id = element.attributeValue("id");
        String clazz = element.attributeValue("class");
        // 获取Class类对象
        Class clazzType = resolveType(clazz);

        String initMethod = element.attributeValue("init-method");
        String scope = element.attributeValue("scope");
        // 保证scope不能为空
        scope = scope == null || scope.equals("") ? "singleton":scope ;

        // 保证id不能为空
        id = id == null || id.equals("") ? clazzType.getSimpleName() : id;

        BeanDefinition bd = new BeanDefinition(clazz,id);
        bd.setScope(scope);
        bd.setInitMethod(initMethod);

        List<Element> elements = element.elements("property");
        for (Element propertyElement : elements) {
            bd.addPropertyValue(parsePropertyElement(propertyElement));
        }

        this.registry.registerBeanDefinition(id,bd);

    }

    private Class resolveType(String clazz) {
        try {
            return Class.forName(clazz);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

    private PropertyValue parsePropertyElement(Element propertyElement) {
        String name = propertyElement.attributeValue("name");
        String value = propertyElement.attributeValue("value");
        String ref = propertyElement.attributeValue("ref");

        if (value != null && ref != null){
            return null;
        }
        PropertyValue pv = null;
        if (value != null){
            TypedStringValue typedStringValue = new TypedStringValue(value);
            pv = new PropertyValue(name,typedStringValue);
        }else if (ref != null){
            RuntimeBeanReference beanReference = new RuntimeBeanReference(ref);
            pv = new PropertyValue(name,beanReference);
        }

        return pv;
    }

    private Document getDocument(InputStream inputStream) {
        try {
            SAXReader saxReader = new SAXReader();
            return saxReader.read(inputStream);
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        return null;
    }
}
